package com.xsd.juc;


import java.util.concurrent.TimeUnit;

/**
 * @Description: 多线程锁
 * @Author: zhoufuzong
 * @Created: 2020-12-31 22:26:01
 * @Version: 1.1.0
 */

class Phone{

    public  static synchronized void sendEmail(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("----sendEmail");

    }

   public    synchronized void sendSMS(){
       System.out.println("----sendSMS");

   }

   public void hello(){
       System.out.println("----hello");
   }

}


/**
 * 题目 多线程锁
 * 1. 标准访问，请问先打印邮件还是短信 sleep                  邮件
*       一个对象里面如果有多个synchronized方法，某一时刻内，只要一个线程去调用其中的一个synchronized
 *       其他线程都得等待，即某一个时刻内，只能有唯一一个线程去访问这些synchronized方法
 *         synchronized  锁的是方法所在的整个资源类，即当前对象this，
 *         被锁定后，其他线程都不能进入到当前对象的其他的synchronized方法
 *         即同一时间段不可能有两个线程同时访问同一个资源类
 *         即同一时间段只允许有一个线程访问同一个资源类的其中一个synchronized 方法
 *
 * 2. 邮件方法暂停4秒钟，请问邮件先打印邮件还是短信            邮件
 *    ***** 1, 2 ，A 线程先进来 锁住了整个对象，因而先打印邮件
 *
 * 3.新增一个普通方法hello(),请问先打印邮件还是hello()         hello，
 * 4. 两部手机，请问先打印邮件，还是短信                       短信
 *     普通方法和同步锁无关，如果message 在前 hello在后，那么先打印message
 *     换成两个对象以后，不是同一把锁了，情况立刻变化
 *
 * 5. 两个静态同步方法，用一部手机,请问先打印邮件还是 短信 :     邮件
 * 6. 两个静态同步方法， 2 部手机,请问先打印邮件还是短信：       邮件
 *
 *
 * 7  1个普通同步方法，一个静态同步方法，1部手机 请问先打印邮件还是短信    短信
 * 普通同步方法-短线，静态同步 邮件
 * 8  1个普通同步方法，一个静态同步方法，2部手机 请问先打印邮件还是 短信   短信
 *
 * 都换成静态同步方法后，情况又变化
 * new this,具体唯一一部手机
 * 静态class , 唯一的一个模板
 *
 * 所有的非静态同步方法用的都是同一把锁———— 实例对象本身
 * synchronized 实现同步的基础：java 中的每一个对象都可以作为锁。
 *
 * 具体表现为以下3种形式
 * 对于普通同步方法，锁是当前实例对象。
 * 对于静态同步方法，锁是当前实例对象。
 * 对于同步方法块，锁是synchronized括号里配置的对象
 *
 * 当一个线程试图访问同步代码块时，它首先必须得到锁，退出或抛出异常时必须释放锁。
 *
 * 也就是说如果一个实例对象的非静态同步方法获取锁后，
 * 该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁
 * 可是别的实例对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁，
 * 所以不用等待该实例对象掉已获取锁的非静态同步方法释放锁就可以获取他们自己的锁
 *
 * 所有静态同步方法用的也是同一个把锁——类对象本身，
 * 这两把锁是两个不同的对象，所以静态同步方法与非静态同步方法之间是不会有竞态条件的。
 * 但是一旦一个静态同步方法获取锁以后，其他的静态同步方法都必须等待该方法释放锁以后才能获取锁
 * 而不管是同一个实例对象的静态同步方法之间，
 * 还是不同的实例对象的静态同步方法之间，只要他们是同一个列的实例对象
 *
 *
 *
 */
public class Lock8 {
    public static void main(String[] args) throws Exception {
        Phone phone =new Phone();
        Phone phone1 = new Phone();

        new Thread(()->{

//            phone.sendEmail();
            phone.sendEmail();
        },"A").start();


        Thread.sleep(100);


        new Thread(()->{
//            phone.sendSMS();
//            phone1.sendSMS();
//
            phone.sendSMS();
//            phone.hello();

        },"B").start();
    }
}
